package io.renren.modules.iots.utils.socket.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;

import io.renren.modules.iots.utils.comment.IotpBodyUtils;
import io.renren.modules.iots.utils.comment.Msg_rellect;

/**
 * @ClassName: SocketBean
 * @Description: socket实体类
 * @author 周西栋
 * @date 2018年5月9日
 *
 */
public class SocketBean {
	
	/**
     * 创建一个新的实例 TCPClient.
     *
     * @param HostIp
     * @param HostListenningPort
     * @throws IOException
     */
    public SocketBean(String serverip, int serverport) throws IOException {
        this.serverip = serverip;
        this.serverport = serverport;
        setLasttry(this.changetime);
        initialize();
    }

	/**
	 * 客户端ip
	 */
	private String serverip;
	
	/**
	 * 客户端port
	 */
	private Integer serverport;
	
	/**
	 * 超时时间（单位/秒）
	 * 默认值1800
	 */
	private Integer outtime = 10;
	
	/**
	 * 尝试连接的最后时间
	 */
	private Date lasttry;

	/**
	 * 连接的状态
	 * ***  默认是  "初始化" ***
	 * 状态值分别是：1.初始化、2.尝试中、3.已连接、4.未连接
	 * 1.初始化--指对象刚创建，还没有连接动作
	 * 2.尝试中--指尝试建立连接
	 * 3.已连接--指已经建立了连接，可以通讯的状态
	 * 4.未连接--指没有连接成功，或连接超时断开的状态
	 */
	private int connectstatus = 1;
	
	/**
	 * 上次与现在不同的连接的状态
	 * ***  默认是  "初始化" ***
	 * 状态值分别是：1.初始化、2.尝试中、3.已连接、4.未连接
	 * 1.初始化--指对象刚创建，还没有连接动作
	 * 2.尝试中--指尝试建立连接
	 * 3.已连接--指已经建立了连接，可以通讯的状态
	 * 4.未连接--指没有连接成功，或连接超时断开的状态
	 */
	private int beforeDiffConnectStatus = 1;
	
	/**
	 * 上次的连接的状态
	 * ***  默认是  "初始化" ***
	 * 状态值分别是：1.初始化、2.尝试中、3.已连接、4.未连接
	 * 1.初始化--指对象刚创建，还没有连接动作
	 * 2.尝试中--指尝试建立连接
	 * 3.已连接--指已经建立了连接，可以通讯的状态
	 * 4.未连接--指没有连接成功，或连接超时断开的状态
	 */
	private int beforeConnectStatus = 1;
	
	/**
	 * 连接状态改变的时间
	 */
	private Date changetime = new Date();
	
	/**
	 * 选择器
	 */
	private Selector selector;
	
	/**
	 * 关键字
	 */
	private SelectionKey selectionKey;
	
	/**
	 * 通道
	 */
	private SocketChannel socketChannel;

	public String getServerip() {
		return serverip;
	}

	public void setServerip(String serverip) {
		this.serverip = serverip;
	}

	public Integer getServerport() {
		return serverport;
	}

	public void setServerport(Integer serverport) {
		this.serverport = serverport;
	}

	public Integer getOuttime() {
		return outtime;
	}

	public void setOuttime(Integer outtime) {
		this.outtime = outtime;
	}
	
	public Date getLasttry() {
		return lasttry;
	}

	private void setLasttry(Date lasttry) {
		this.lasttry = new Date(lasttry.getTime() + new Long(outtime*1000).longValue());
	}

	public int getConnectstatus() {
		return connectstatus;
	}

	public void setConnectstatus(int connectstatus) {
		this.connectstatus = connectstatus;
	}

	public int getBeforeDiffConnectStatus() {
		return beforeDiffConnectStatus;
	}

	public void setBeforeDiffConnectStatus(int beforeDiffConnectStatus) {
		this.beforeDiffConnectStatus = beforeDiffConnectStatus;
	}

	public int getBeforeConnectStatus() {
		return beforeConnectStatus;
	}

	public void setBeforeConnectStatus(int beforeConnectStatus) {
		this.beforeConnectStatus = beforeConnectStatus;
	}

	public Date getChangetime() {
		return changetime;
	}

	public void setChangetime(Date changetime) {
		this.changetime = changetime;
		setLasttry(changetime);
	}

	public Selector getSelector() {
		return selector;
	}

	public void setSelector(Selector selector) {
		this.selector = selector;
	}

	public SelectionKey getSelectionKey() {
		return selectionKey;
	}

	public void setSelectionKey(SelectionKey selectionKey) {
		this.selectionKey = selectionKey;
	}

	public SocketChannel getSocketChannel() {
		return socketChannel;
	}

	public void setSocketChannel(SocketChannel socketChannel) {
		this.socketChannel = socketChannel;
	}
	
	/**
	 * @Title: initialize
	 * @Description: 初始化
	 * @param     参数
	 * @return void    返回类型
	 * @throws
	 */
	public void initialize(){
		try {
            // 获得一个Socket通道
			socketChannel = SocketChannel.open();
            // 设置通道为非阻塞
			socketChannel.configureBlocking(false);
            // 获得一个通道管理器
            this.selector = Selector.open();
            // 客户端连接服务器,其实方法执行并没有实现连接，需要在listen（）方法中调
            //用channel.finishConnect();才能完成连接
            socketChannel.connect(new InetSocketAddress(serverip, serverport));
            //将通道管理器和该通道绑定，并为该通道注册SelectionKey.OP_CONNECT事件。
            selectionKey = socketChannel.register(selector, SelectionKey.OP_CONNECT);
            // 管理连接
            SocketUtils.SOCKETBEAN_MAP.put((serverip+":"+serverport), this);
            // 管理通道
            SocketUtils.CHANNEL_IOTPBODYUTILS_MAP.put(this, new IotpBodyUtils());
            // 接收数据拼接工具
            SocketUtils.RELLECTMESSAGE.put(this, new Msg_rellect());
        } catch (Exception e) {
            System.out.println(e.toString());
        }
	}

	@Override
	public String toString() {
		return "SocketBean [serverip=" + serverip + ", serverport=" + serverport + ", outtime=" + outtime
				+ ", lasttry=" + lasttry + ", connectstatus=" + connectstatus + ", beforeDiffConnectStatus=" + beforeDiffConnectStatus
				+ ", beforeConnectStatus=" + beforeConnectStatus + ", changetime=" + changetime + ", selector="
				+ selector + ", selectionKey=" + selectionKey + ", socketChannel=" + socketChannel + "]";
	}
	
	
}
